Población de países del Banco Mundial

Vamos a importar los datos world_bank_pop.csv. Lo primero siempre es cargar las paqueterías necesarias.

library(tidyverse)
library(lubridate)
library(patchwork)
library(tidyquant)
library(plotly)

Vamos a cargar los datos. Para que sea más fácil y reproducible su R Notebook, es necesario que estén guardados dentro de la carpeta en donde se encuentra su proyecto.

wb_pop <- read_csv("data/world_bank_pop.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  country = col_character(),
  indicator = col_character()
)
See spec(...) for full column specifications.
wb_pop

Vemos que los datos no están limpios.

Lo primero que tenemos que hacer es pasar los años a filas. Usaremos pivot_longer() de la paquetería tidyr.

wb_pop_long <-  wb_pop %>% 
  pivot_longer(cols = -c(country, indicator),
               names_to = "año", values_to = "valor"
               ) %>%
  mutate(año = as.integer(año))
wb_pop_long

Ahora queremos pasar los indicadores a columnas distintas.

wb_pop_long %>% 
  pivot_wider(names_from = indicator,
              values_from = valor)

Pudimos haber hecho estos dos pasos en uno solo, con ayuda de los pipes (%>%).

wb_pop_tidy <- wb_pop %>% 
  # primero pasamos los años a filas
  pivot_longer(cols = -c(country, indicator),
               names_to = "año", values_to = "valor"
               ) %>% 
  # cambiamos los años para que sean números enteros
  mutate(año = as.integer(año)) %>% 
  # ahora pasamos los indicadores a columnas
  pivot_wider(names_from = indicator,
              values_from = valor) %>% 
  # cambio la variable country a factores
  mutate(country = as_factor(country))

wb_pop_tidy

Si quisiéramos ver solo los datos para México, podemos usar filter().

Para quedarnos solo con datos de México:

wb_pop_tidy %>% 
  filter(country == "MEX")

Para quedarnos con datos de México y solo las variables de año y población urbana total:

wb_pop_tidy %>% 
  filter(country == "MEX") %>% 
  select(año, SP.URB.TOTL)

Ahora, si quisiéramos todas las variables, menos SP.URB.TOTL, para México y Brasil:

wb_pop_tidy %>% 
  filter(country %in% c("MEX","BRA")) %>% 
  select(-SP.URB.TOTL)

Si queremos deducir cuál es la población rural por país, tendríamos que agregar una nueva variable. Lo haremos con mutate().

wb_pop_tidy %>% 
  filter(country %in% c("MEX","BRA","CAN")) %>% 
  mutate(pob_rural = SP.POP.TOTL - SP.URB.TOTL)

Si quisiéramos saber el % de la población que vive en las zonas rurales, podríamos hacerlo igualmente con mutate().

wb_pop_tidy <-  wb_pop_tidy %>% 
  filter(country %in% c("MEX","BRA","CAN")) %>% 
  mutate(pob_rural = SP.POP.TOTL - SP.URB.TOTL,
         pct_rural = pob_rural / SP.POP.TOTL,
         pct_urbana = 1 - pct_rural)
wb_pop_tidy

Vamos a graficar el crecimiento de la población total a lo largo del tiempo.

g <- ggplot(data = wb_pop_tidy, aes(x = año, color = country))

g + geom_line(aes(y = SP.POP.TOTL)) +
  labs(title = "Crecimiento de la población en el tiempo",
       y = "Población total",
       x = "",
       color = "") 

Podemos utilizar una escala logarítmica en el eje y para visualizar mejor los datos.

g + geom_line(aes(y = SP.POP.TOTL)) + scale_y_log10()

g + geom_line(aes(y = pct_rural)) +
  geom_line(aes(y = pct_urbana))

g + geom_line(aes(y = pct_rural)) +
  geom_line(aes(y = pct_urbana)) +
  facet_wrap(~ country)

p1 <- g + geom_line(aes(y = pct_rural)) +
  theme(legend.position = "none")

p2 <- g + geom_line(aes(y = pct_urbana)) + 
  theme(legend.position = "none")

p3 <- g + geom_line(aes(y = SP.POP.TOTL)) + scale_y_log10()
p1 + p2 + p3


p1 / p2 /p3


p3 / (p1 + p2) + 
  plot_annotation(title = "Acomodando varias gráficas con patchwork",
                  subtitle = "Población total y evolución de la población urbana y rural")

Si quisiéramos graficar por separado cada una de las variables, podríamos crear un código genérico y solo cambiar la variable y. Algo como:

p <- wb_pop_tidy %>% 
  ggplot(aes(x = año, color = country)) + geom_line()

p + aes(y = SP.URB.TOTL)

p + aes(y = SP.URB.GROW)

p + aes(y = SP.POP.TOTL)

p + aes(y = SP.POP.GROW)

p + aes(y = pob_rural)

p + aes(y = pct_rural)

p + aes(y = pct_urbana)

Sin embargo, aunque pudimos ahorrarnos bastante código guardando la estructura básica de cada gráfica en p, tuvimos que repetir varias veces lo mismo y nos quedaron gráficas separadas. Si lo que necesitamos es tener todas en una misma imagen, podríamos unirlas con patchwork, pero sería más trabajo.

En cambio, podemos hacer un hack y utilizar pivot_longer() para lograr hacer esto en un solo paso:

wb_pop_tidy %>% 
  # pasamos todas las columnas de variables a una sola
  pivot_longer(cols = -c(country, año),
               names_to = "indicador",
               values_to = "valor") %>% 
  # graficamos y separamos por facetas cada indicador
  ggplot(aes(x = año, y = valor, color = country)) +
  geom_line() + 
  facet_wrap(~ indicador, scales = "free_y")

Ventas de autos totales en EEUU

autos <- tq_get("TOTALNSA", get = "economic.data", 
                from = "1977-01-01")
autos

Vamos a quitar la variable symbol que no nos aporta información relevante (con select()), y vamos a renombrar la variable price para que se llame ventas.

autos <- autos %>% 
  select(-symbol) %>% 
  rename(ventas = price)
autos
autos %>%
  slice_tail(n = 10)
p <- autos %>% 
  ggplot(aes(x = date, y = ventas)) +
  geom_line()

p

ggplotly(p)

Esta gráfica nos muestra que la serie presenta una fuerte estacionaliadad

Agregando líneas y etiquetas para mostrar las crisis.

p + 
  geom_vline(xintercept = dmy("01-10-2008"),
             linetype = "dashed", 
             color = "red",
             size = 1.5) +
  geom_vline(xintercept = ymd("2020-03-01"),
             linetype = "dotted", 
             color = "darkgreen",
             size = 1.5) + 
  annotate(geom = "label", 
           x = c(ymd("2008-10-01"),
                 ymd("2020-03-01")),
           y = c(1700,1700), 
           label = c("Inmobiliaria '08", "COVID-19"), 
           color = c("red", "darkgreen"), 
           size = 3) +
  labs(title = "Ventas totales de autos en EEUU",
       x = "",
       y = "Miles de unidades"
       ) +
  theme_minimal()

p + geom_hline(yintercept = max(autos$ventas),
               linetype = 4, 
               size = 1.2, 
               color = "purple") +
  geom_hline(yintercept = min(autos$ventas),
             linetype = 5, 
             size = 1.2, 
             color = "turquoise1") +
geom_hline(yintercept = mean(autos$ventas), 
           linetype = 8, 
           size = 1, 
           color = "orchid2") +
  annotate("label",
           x = ymd("1980-01-01"),
           y = c(max(autos$ventas), 
                 min(autos$ventas), 
                 mean(autos$ventas)), 
           label = c("Máximo histórico", 
                     "Mínimo", 
                     "Ventas promedio"),
           color = c("purple",
                     "turquoise1", 
                     "orchid2"))

LS0tDQp0aXRsZTogIkltcG9ydGFjacOzbiB5IGxpbXBpZXphIGRlIGRhdG9zIg0KYXV0aG9yOiAiUGFibG8gQmVuYXZpZGVzIEhlcnJlcmEiDQpkYXRlOiAyMDIwLTA2LTAxDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOg0KICAgIHRoZW1lOiB1bml0ZWQNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQotLS0NCg0KIyBQb2JsYWNpw7NuIGRlIHBhw61zZXMgZGVsIEJhbmNvIE11bmRpYWwNCg0KVmFtb3MgYSBpbXBvcnRhciBsb3MgZGF0b3MgYHdvcmxkX2JhbmtfcG9wLmNzdmAuIExvIHByaW1lcm8gc2llbXByZSBlcyBjYXJnYXIgbGFzIHBhcXVldGVyw61hcyBuZWNlc2FyaWFzLg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHBhdGNod29yaykNCmxpYnJhcnkodGlkeXF1YW50KQ0KbGlicmFyeShwbG90bHkpDQpgYGANCg0KVmFtb3MgYSBjYXJnYXIgbG9zIGRhdG9zLiBQYXJhIHF1ZSBzZWEgbcOhcyBmw6FjaWwgeSByZXByb2R1Y2libGUgc3UgUiBOb3RlYm9vaywgZXMgbmVjZXNhcmlvIHF1ZSBlc3TDqW4gZ3VhcmRhZG9zIGRlbnRybyBkZSBsYSBjYXJwZXRhIGVuIGRvbmRlIHNlIGVuY3VlbnRyYSBzdSBwcm95ZWN0by4NCg0KYGBge3J9DQp3Yl9wb3AgPC0gcmVhZF9jc3YoImRhdGEvd29ybGRfYmFua19wb3AuY3N2IikNCndiX3BvcA0KYGBgDQoNClZlbW9zIHF1ZSBsb3MgZGF0b3Mgbm8gZXN0w6FuIGxpbXBpb3MuDQoNCkxvIHByaW1lcm8gcXVlIHRlbmVtb3MgcXVlIGhhY2VyIGVzIHBhc2FyIGxvcyBhw7FvcyBhIGZpbGFzLiBVc2FyZW1vcyBgcGl2b3RfbG9uZ2VyKClgIGRlIGxhIHBhcXVldGVyw61hIGB0aWR5cmAuDQoNCmBgYHtyfQ0Kd2JfcG9wX2xvbmcgPC0gIHdiX3BvcCAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gLWMoY291bnRyeSwgaW5kaWNhdG9yKSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImHDsW8iLCB2YWx1ZXNfdG8gPSAidmFsb3IiDQogICAgICAgICAgICAgICApICU+JQ0KICBtdXRhdGUoYcOxbyA9IGFzLmludGVnZXIoYcOxbykpDQp3Yl9wb3BfbG9uZw0KYGBgDQoNCg0KQWhvcmEgcXVlcmVtb3MgcGFzYXIgbG9zIGluZGljYWRvcmVzIGEgY29sdW1uYXMgZGlzdGludGFzLg0KDQpgYGB7cn0NCndiX3BvcF9sb25nICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGluZGljYXRvciwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSB2YWxvcikNCmBgYA0KDQpQdWRpbW9zIGhhYmVyIGhlY2hvIGVzdG9zIGRvcyBwYXNvcyBlbiB1bm8gc29sbywgY29uIGF5dWRhIGRlIGxvcyBwaXBlcyAoYCAlPiUgYCkuDQoNCmBgYHtyfQ0Kd2JfcG9wX3RpZHkgPC0gd2JfcG9wICU+JSANCiAgIyBwcmltZXJvIHBhc2Ftb3MgbG9zIGHDsW9zIGEgZmlsYXMNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtYyhjb3VudHJ5LCBpbmRpY2F0b3IpLA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiYcOxbyIsIHZhbHVlc190byA9ICJ2YWxvciINCiAgICAgICAgICAgICAgICkgJT4lIA0KICAjIGNhbWJpYW1vcyBsb3MgYcOxb3MgcGFyYSBxdWUgc2VhbiBuw7ptZXJvcyBlbnRlcm9zDQogIG11dGF0ZShhw7FvID0gYXMuaW50ZWdlcihhw7FvKSkgJT4lIA0KICAjIGFob3JhIHBhc2Ftb3MgbG9zIGluZGljYWRvcmVzIGEgY29sdW1uYXMNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGluZGljYXRvciwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSB2YWxvcikgJT4lIA0KICAjIGNhbWJpbyBsYSB2YXJpYWJsZSBjb3VudHJ5IGEgZmFjdG9yZXMNCiAgbXV0YXRlKGNvdW50cnkgPSBhc19mYWN0b3IoY291bnRyeSkpDQoNCndiX3BvcF90aWR5DQpgYGANCg0KU2kgcXVpc2nDqXJhbW9zIHZlciBzb2xvIGxvcyBkYXRvcyBwYXJhIE3DqXhpY28sIHBvZGVtb3MgdXNhciBgZmlsdGVyKClgLg0KDQpQYXJhIHF1ZWRhcm5vcyBzb2xvIGNvbiBkYXRvcyBkZSBNw6l4aWNvOg0KYGBge3J9DQp3Yl9wb3BfdGlkeSAlPiUgDQogIGZpbHRlcihjb3VudHJ5ID09ICJNRVgiKQ0KYGBgDQoNClBhcmEgcXVlZGFybm9zIGNvbiBkYXRvcyBkZSBNw6l4aWNvIHkgc29sbyBsYXMgdmFyaWFibGVzIGRlIGHDsW8geSBwb2JsYWNpw7NuIHVyYmFuYSB0b3RhbDoNCg0KYGBge3J9DQp3Yl9wb3BfdGlkeSAlPiUgDQogIGZpbHRlcihjb3VudHJ5ID09ICJNRVgiKSAlPiUgDQogIHNlbGVjdChhw7FvLCBTUC5VUkIuVE9UTCkNCmBgYA0KDQpBaG9yYSwgc2kgcXVpc2nDqXJhbW9zICoqdG9kYXMqKiBsYXMgdmFyaWFibGVzLCBtZW5vcyBgU1AuVVJCLlRPVExgLCBwYXJhIE3DqXhpY28geSBCcmFzaWw6DQoNCmBgYHtyfQ0Kd2JfcG9wX3RpZHkgJT4lIA0KICBmaWx0ZXIoY291bnRyeSAlaW4lIGMoIk1FWCIsIkJSQSIpKSAlPiUgDQogIHNlbGVjdCgtU1AuVVJCLlRPVEwpDQpgYGANCg0KU2kgcXVlcmVtb3MgZGVkdWNpciBjdcOhbCBlcyBsYSBwb2JsYWNpw7NuIHJ1cmFsIHBvciBwYcOtcywgdGVuZHLDrWFtb3MgcXVlIGFncmVnYXIgdW5hIG51ZXZhIHZhcmlhYmxlLiBMbyBoYXJlbW9zIGNvbiBgbXV0YXRlKClgLg0KDQpgYGB7cn0NCndiX3BvcF90aWR5ICU+JSANCiAgZmlsdGVyKGNvdW50cnkgJWluJSBjKCJNRVgiLCJCUkEiLCJDQU4iKSkgJT4lIA0KICBtdXRhdGUocG9iX3J1cmFsID0gU1AuUE9QLlRPVEwgLSBTUC5VUkIuVE9UTCkNCmBgYA0KDQpTaSBxdWlzacOpcmFtb3Mgc2FiZXIgZWwgJSBkZSBsYSBwb2JsYWNpw7NuIHF1ZSB2aXZlIGVuIGxhcyB6b25hcyBydXJhbGVzLCBwb2Ryw61hbW9zIGhhY2VybG8gaWd1YWxtZW50ZSBjb24gYG11dGF0ZSgpYC4NCg0KYGBge3J9DQp3Yl9wb3BfdGlkeSA8LSAgd2JfcG9wX3RpZHkgJT4lIA0KICBmaWx0ZXIoY291bnRyeSAlaW4lIGMoIk1FWCIsIkJSQSIsIkNBTiIpKSAlPiUgDQogIG11dGF0ZShwb2JfcnVyYWwgPSBTUC5QT1AuVE9UTCAtIFNQLlVSQi5UT1RMLA0KICAgICAgICAgcGN0X3J1cmFsID0gcG9iX3J1cmFsIC8gU1AuUE9QLlRPVEwsDQogICAgICAgICBwY3RfdXJiYW5hID0gMSAtIHBjdF9ydXJhbCkNCndiX3BvcF90aWR5DQpgYGANCg0KVmFtb3MgYSBncmFmaWNhciBlbCBjcmVjaW1pZW50byBkZSBsYSAqKnBvYmxhY2nDs24gdG90YWwqKiBhIGxvIGxhcmdvIGRlbCB0aWVtcG8uDQoNCmBgYHtyfQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IHdiX3BvcF90aWR5LCBhZXMoeCA9IGHDsW8sIGNvbG9yID0gY291bnRyeSkpDQoNCmcgKyBnZW9tX2xpbmUoYWVzKHkgPSBTUC5QT1AuVE9UTCkpICsNCiAgbGFicyh0aXRsZSA9ICJDcmVjaW1pZW50byBkZSBsYSBwb2JsYWNpw7NuIGVuIGVsIHRpZW1wbyIsDQogICAgICAgeSA9ICJQb2JsYWNpw7NuIHRvdGFsIiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgY29sb3IgPSAiIikgDQpgYGANCg0KUG9kZW1vcyB1dGlsaXphciB1bmEgZXNjYWxhIGxvZ2Fyw610bWljYSBlbiBlbCBlamUgKnkqIHBhcmEgdmlzdWFsaXphciBtZWpvciBsb3MgZGF0b3MuDQoNCmBgYHtyfQ0KZyArIGdlb21fbGluZShhZXMoeSA9IFNQLlBPUC5UT1RMKSkgKyBzY2FsZV95X2xvZzEwKCkNCmBgYA0KDQpgYGB7cn0NCmcgKyBnZW9tX2xpbmUoYWVzKHkgPSBwY3RfcnVyYWwpKSArDQogIGdlb21fbGluZShhZXMoeSA9IHBjdF91cmJhbmEpKQ0KYGBgDQoNCmBgYHtyfQ0KZyArIGdlb21fbGluZShhZXMoeSA9IHBjdF9ydXJhbCkpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gcGN0X3VyYmFuYSkpICsNCiAgZmFjZXRfd3JhcCh+IGNvdW50cnkpDQpgYGANCg0KYGBge3J9DQpwMSA8LSBnICsgZ2VvbV9saW5lKGFlcyh5ID0gcGN0X3J1cmFsKSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCnAyIDwtIGcgKyBnZW9tX2xpbmUoYWVzKHkgPSBwY3RfdXJiYW5hKSkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQpwMyA8LSBnICsgZ2VvbV9saW5lKGFlcyh5ID0gU1AuUE9QLlRPVEwpKSArIHNjYWxlX3lfbG9nMTAoKQ0KYGBgDQoNCg0KYGBge3J9DQpwMSArIHAyICsgcDMNCg0KcDEgLyBwMiAvcDMNCg0KcDMgLyAocDEgKyBwMikgKyANCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIkFjb21vZGFuZG8gdmFyaWFzIGdyw6FmaWNhcyBjb24gcGF0Y2h3b3JrIiwNCiAgICAgICAgICAgICAgICAgIHN1YnRpdGxlID0gIlBvYmxhY2nDs24gdG90YWwgeSBldm9sdWNpw7NuIGRlIGxhIHBvYmxhY2nDs24gdXJiYW5hIHkgcnVyYWwiKQ0KYGBgDQpgYGB7cn0NCndiX3BvcF90aWR5ICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKHBjdF9ydXJhbCwgcGN0X3VyYmFuYSksDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ6b25hIiwgDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAicG9yY2VudGFqZXMiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGHDsW8sIHkgPSBwb3JjZW50YWplcywgZmlsbCA9IHpvbmEpKSArDQogIGdlb21fYXJlYSgpICsgZmFjZXRfd3JhcCh2YXJzKGNvdW50cnkpKQ0KYGBgDQoNClNpIHF1aXNpw6lyYW1vcyBncmFmaWNhciBwb3Igc2VwYXJhZG8gY2FkYSB1bmEgZGUgbGFzIHZhcmlhYmxlcywgcG9kcsOtYW1vcyBjcmVhciB1biBjw7NkaWdvIGdlbsOpcmljbyB5IHNvbG8gY2FtYmlhciBsYSB2YXJpYWJsZSBgeWAuIEFsZ28gY29tbzoNCg0KYGBge3J9DQpwIDwtIHdiX3BvcF90aWR5ICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gYcOxbywgY29sb3IgPSBjb3VudHJ5KSkgKyBnZW9tX2xpbmUoKQ0KDQpwICsgYWVzKHkgPSBTUC5VUkIuVE9UTCkNCnAgKyBhZXMoeSA9IFNQLlVSQi5HUk9XKQ0KcCArIGFlcyh5ID0gU1AuUE9QLlRPVEwpDQpwICsgYWVzKHkgPSBTUC5QT1AuR1JPVykNCnAgKyBhZXMoeSA9IHBvYl9ydXJhbCkNCnAgKyBhZXMoeSA9IHBjdF9ydXJhbCkNCnAgKyBhZXMoeSA9IHBjdF91cmJhbmEpDQpgYGANClNpbiBlbWJhcmdvLCBhdW5xdWUgcHVkaW1vcyAqYWhvcnJhcm5vcyogYmFzdGFudGUgY8OzZGlnbyBndWFyZGFuZG8gbGEgZXN0cnVjdHVyYSBiw6FzaWNhIGRlIGNhZGEgZ3LDoWZpY2EgZW4gYHBgLCB0dXZpbW9zIHF1ZSByZXBldGlyIHZhcmlhcyB2ZWNlcyBsbyBtaXNtbyB5IG5vcyBxdWVkYXJvbiBncsOhZmljYXMgc2VwYXJhZGFzLiBTaSBsbyBxdWUgbmVjZXNpdGFtb3MgZXMgdGVuZXIgdG9kYXMgZW4gdW5hIG1pc21hIGltYWdlbiwgcG9kcsOtYW1vcyB1bmlybGFzIGNvbiBgcGF0Y2h3b3JrYCwgcGVybyBzZXLDrWEgbcOhcyB0cmFiYWpvLg0KDQpFbiBjYW1iaW8sIHBvZGVtb3MgaGFjZXIgdW4gKmhhY2sqIHkgdXRpbGl6YXIgYHBpdm90X2xvbmdlcigpYCBwYXJhIGxvZ3JhciBoYWNlciBlc3RvIGVuIHVuIHNvbG8gcGFzbzoNCg0KYGBge3J9DQp3Yl9wb3BfdGlkeSAlPiUgDQogICMgcGFzYW1vcyB0b2RhcyBsYXMgY29sdW1uYXMgZGUgdmFyaWFibGVzIGEgdW5hIHNvbGENCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtYyhjb3VudHJ5LCBhw7FvKSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImluZGljYWRvciIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsb3IiKSAlPiUgDQogICMgZ3JhZmljYW1vcyB5IHNlcGFyYW1vcyBwb3IgZmFjZXRhcyBjYWRhIGluZGljYWRvcg0KICBnZ3Bsb3QoYWVzKHggPSBhw7FvLCB5ID0gdmFsb3IsIGNvbG9yID0gY291bnRyeSkpICsNCiAgZ2VvbV9saW5lKCkgKyANCiAgZmFjZXRfd3JhcCh+IGluZGljYWRvciwgc2NhbGVzID0gImZyZWVfeSIpDQpgYGANCg0KDQoNCg0KIyBWZW50YXMgZGUgYXV0b3MgdG90YWxlcyBlbiBFRVVVDQoNCmBgYHtyfQ0KYXV0b3MgPC0gdHFfZ2V0KCJUT1RBTE5TQSIsIGdldCA9ICJlY29ub21pYy5kYXRhIiwgDQogICAgICAgICAgICAgICAgZnJvbSA9ICIxOTc3LTAxLTAxIikNCmF1dG9zDQpgYGANCg0KVmFtb3MgYSBxdWl0YXIgbGEgdmFyaWFibGUgYHN5bWJvbGAgcXVlIG5vIG5vcyBhcG9ydGEgaW5mb3JtYWNpw7NuIHJlbGV2YW50ZSAoY29uIGBzZWxlY3QoKWApLCB5IHZhbW9zIGEgcmVub21icmFyIGxhIHZhcmlhYmxlIGBwcmljZWAgcGFyYSBxdWUgc2UgbGxhbWUgYHZlbnRhc2AuDQoNCmBgYHtyfQ0KYXV0b3MgPC0gYXV0b3MgJT4lIA0KICBzZWxlY3QoLXN5bWJvbCkgJT4lIA0KICByZW5hbWUodmVudGFzID0gcHJpY2UpDQphdXRvcw0KYGBgDQoNCmBgYHtyfQ0KYXV0b3MgJT4lDQogIHNsaWNlX3RhaWwobiA9IDEwKQ0KYGBgDQoNCg0KYGBge3J9DQpwIDwtIGF1dG9zICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHZlbnRhcykpICsNCiAgZ2VvbV9saW5lKCkNCg0KcA0KZ2dwbG90bHkocCkNCmBgYA0KDQpFc3RhIGdyw6FmaWNhIG5vcyBtdWVzdHJhIHF1ZSBsYSBzZXJpZSBwcmVzZW50YSB1bmEgZnVlcnRlICoqZXN0YWNpb25hbGlhZGFkKioNCg0KDQpBZ3JlZ2FuZG8gbMOtbmVhcyB5IGV0aXF1ZXRhcyBwYXJhIG1vc3RyYXIgbGFzIGNyaXNpcy4NCg0KYGBge3J9DQpwICsgDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGRteSgiMDEtMTAtMjAwOCIpLA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIA0KICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsDQogICAgICAgICAgICAgc2l6ZSA9IDEuNSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSB5bWQoIjIwMjAtMDMtMDEiKSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkb3R0ZWQiLCANCiAgICAgICAgICAgICBjb2xvciA9ICJkYXJrZ3JlZW4iLA0KICAgICAgICAgICAgIHNpemUgPSAxLjUpICsgDQogIGFubm90YXRlKGdlb20gPSAibGFiZWwiLCANCiAgICAgICAgICAgeCA9IGMoeW1kKCIyMDA4LTEwLTAxIiksDQogICAgICAgICAgICAgICAgIHltZCgiMjAyMC0wMy0wMSIpKSwNCiAgICAgICAgICAgeSA9IGMoMTcwMCwxNzAwKSwgDQogICAgICAgICAgIGxhYmVsID0gYygiSW5tb2JpbGlhcmlhICcwOCIsICJDT1ZJRC0xOSIpLCANCiAgICAgICAgICAgY29sb3IgPSBjKCJyZWQiLCAiZGFya2dyZWVuIiksIA0KICAgICAgICAgICBzaXplID0gMykgKw0KICBsYWJzKHRpdGxlID0gIlZlbnRhcyB0b3RhbGVzIGRlIGF1dG9zIGVuIEVFVVUiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIk1pbGVzIGRlIHVuaWRhZGVzIg0KICAgICAgICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCmBgYHtyfQ0KcCArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IG1heChhdXRvcyR2ZW50YXMpLA0KICAgICAgICAgICAgICAgbGluZXR5cGUgPSA0LCANCiAgICAgICAgICAgICAgIHNpemUgPSAxLjIsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAicHVycGxlIikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtaW4oYXV0b3MkdmVudGFzKSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDUsIA0KICAgICAgICAgICAgIHNpemUgPSAxLjIsIA0KICAgICAgICAgICAgIGNvbG9yID0gInR1cnF1b2lzZTEiKSArDQpnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBtZWFuKGF1dG9zJHZlbnRhcyksIA0KICAgICAgICAgICBsaW5ldHlwZSA9IDgsIA0KICAgICAgICAgICBzaXplID0gMSwgDQogICAgICAgICAgIGNvbG9yID0gIm9yY2hpZDIiKSArDQogIGFubm90YXRlKCJsYWJlbCIsDQogICAgICAgICAgIHggPSB5bWQoIjE5ODAtMDEtMDEiKSwNCiAgICAgICAgICAgeSA9IGMobWF4KGF1dG9zJHZlbnRhcyksIA0KICAgICAgICAgICAgICAgICBtaW4oYXV0b3MkdmVudGFzKSwgDQogICAgICAgICAgICAgICAgIG1lYW4oYXV0b3MkdmVudGFzKSksIA0KICAgICAgICAgICBsYWJlbCA9IGMoIk3DoXhpbW8gaGlzdMOzcmljbyIsIA0KICAgICAgICAgICAgICAgICAgICAgIk3DrW5pbW8iLCANCiAgICAgICAgICAgICAgICAgICAgICJWZW50YXMgcHJvbWVkaW8iKSwNCiAgICAgICAgICAgY29sb3IgPSBjKCJwdXJwbGUiLA0KICAgICAgICAgICAgICAgICAgICAgInR1cnF1b2lzZTEiLCANCiAgICAgICAgICAgICAgICAgICAgICJvcmNoaWQyIikpDQpgYGANCg0KDQoNCg0KDQoNCg==